package com.swz.dcrm.digger;

import android.content.Intent;
import android.util.Log;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.room.Room;

import com.google.gson.Gson;
import com.swz.dcrm.BuildConfig;
import com.swz.dcrm.db.AppDatabase;
import com.swz.dcrm.model.Approval;
import com.swz.dcrm.model.BaseResponse;
import com.swz.dcrm.model.CarBrand;
import com.swz.dcrm.ui.LoginActivity;
import com.swz.dcrm.ui.MyApplication;
import com.swz.dcrm.ui.base.BaseActivity;
import com.swz.dcrm.ui.viewmodel.AnalyzeViewModel;
import com.swz.dcrm.ui.viewmodel.AnnouncementViewModel;
import com.swz.dcrm.ui.viewmodel.ApprovalViewModel;
import com.swz.dcrm.ui.viewmodel.CarBrandViewModel;
import com.swz.dcrm.ui.viewmodel.CarManagementViewModel;
import com.swz.dcrm.ui.viewmodel.CustomerManagementViewModel;
import com.swz.dcrm.ui.viewmodel.GroupViewModel;
import com.swz.dcrm.ui.viewmodel.HomeViewModel;
import com.swz.dcrm.ui.viewmodel.MainViewModel;
import com.swz.dcrm.ui.viewmodel.ScheduleViewModel;
import com.swz.dcrm.ui.viewmodel.StaffViewModel;
import com.swz.dcrm.ui.viewmodel.TodayPlanViewModel;
import com.swz.dcrm.ui.viewmodel.ViewModelFactory;
import com.xh.baselibrary.model.RequestErrBean;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import okio.BufferedSource;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * @author xh on 2019/8/19
 */
@Module
public class AppModule {


    private  String BASE_URL = BuildConfig.BASEURL;

    private FragmentActivity mFragmentActivity;
    private Fragment fragment;
    public AppModule(FragmentActivity fragmentActivity){
        mFragmentActivity=fragmentActivity;
    }

    public AppModule(Fragment fragment){
        mFragmentActivity=fragment.getActivity();
        this.fragment=fragment;
    }

    @Singleton
    @Provides
    AppDatabase providersDataBase(){

        return Room.databaseBuilder(mFragmentActivity, AppDatabase.class, "dcrmdb")
                .allowMainThreadQueries()
                .build();

    }
    @Singleton
    @Provides
    AnalyzeViewModel providesAnalyzeViewModel(ViewModelFactory viewModelFactory){
        AnalyzeViewModel analyzeViewModel=null;
        if(fragment!=null){
            analyzeViewModel=ViewModelProviders.of(fragment,viewModelFactory).get(AnalyzeViewModel.class);
        }else {
            analyzeViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(AnalyzeViewModel.class);
        }

        analyzeViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());
        });
        return analyzeViewModel;
    }
    @Singleton
    @Provides
    ApprovalViewModel providesApprovalViewModel(ViewModelFactory viewModelFactory){
        ApprovalViewModel approvalViewModel;
        if(fragment!=null){
            approvalViewModel=ViewModelProviders.of(fragment,viewModelFactory).get(ApprovalViewModel.class);
        }else {
            approvalViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(ApprovalViewModel.class);
        }
        approvalViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
             BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
             baseActivity.showToast(requestErrBean.getMessage());
         });
        return approvalViewModel;
    }
    @Singleton
    @Provides
    CarManagementViewModel providesCarManagementViewModel(ViewModelFactory viewModelFactory){

        CarManagementViewModel carManagementViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(CarManagementViewModel.class);
        carManagementViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());
            carManagementViewModel.getErrorLiveData().setValue(null);
        });
        return carManagementViewModel;
    }
    @Singleton
    @Provides
    CarBrandViewModel providesCarBrandViewModel(ViewModelFactory viewModelFactory){

        CarBrandViewModel carBrandViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(CarBrandViewModel.class);
        carBrandViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());
            carBrandViewModel.getErrorLiveData().setValue(null);
        });
        return carBrandViewModel;
    }
    @Singleton
    @Provides
    GroupViewModel providesGoalViewModel(ViewModelFactory viewModelFactory){

        GroupViewModel groupViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(GroupViewModel.class);
        groupViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());
            groupViewModel.getErrorLiveData().setValue(null);
        });
        return groupViewModel;
    }
    @Singleton
    @Provides
    StaffViewModel providesStaffViewModel(ViewModelFactory viewModelFactory){
        StaffViewModel staffViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(StaffViewModel.class);
        staffViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());
            staffViewModel.getErrorLiveData().setValue(null);
        });
        return staffViewModel;
    }
    @Singleton
    @Provides
    AnnouncementViewModel providesAnnouncementViewModel(ViewModelFactory viewModelFactory){
        AnnouncementViewModel announcementViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(AnnouncementViewModel.class);
        announcementViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());

            announcementViewModel.getErrorLiveData().setValue(null);
        });
        return announcementViewModel;
    }
    @Singleton
    @Provides
    ScheduleViewModel providesScheduleViewModel(ViewModelFactory viewModelFactory){
        ScheduleViewModel scheduleViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(ScheduleViewModel.class);
        scheduleViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());
            scheduleViewModel.getErrorLiveData().setValue(null);
        });
        return scheduleViewModel;
    }
    @Singleton
    @Provides
    CustomerManagementViewModel providesCustomerManagementViewModel(ViewModelFactory viewModelFactory){
        CustomerManagementViewModel customerManagementViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(CustomerManagementViewModel.class);
        customerManagementViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());
            customerManagementViewModel.getErrorLiveData().setValue(null);
        });
        return customerManagementViewModel;
    }
    @Singleton
    @Provides
    TodayPlanViewModel providesTodayPlanViewModel(ViewModelFactory viewModelFactory){
        TodayPlanViewModel todayPlanViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(TodayPlanViewModel.class);
        todayPlanViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());
            todayPlanViewModel.getErrorLiveData().setValue(null);
        });
        return todayPlanViewModel;
    }
    @Singleton
    @Provides
    MainViewModel providesMainViewModel(ViewModelFactory viewModelFactory){
        return ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(MainViewModel.class);
    }
    @Singleton
    @Provides
    HomeViewModel providesHomeViewModel(ViewModelFactory viewModelFactory){
        HomeViewModel homeViewModel=ViewModelProviders.of(mFragmentActivity,viewModelFactory).get(HomeViewModel.class);

        homeViewModel.getErrorLiveData().observe(mFragmentActivity, requestErrBean -> {
            if(requestErrBean==null){
                return;
            }
            BaseActivity baseActivity= (BaseActivity) mFragmentActivity;
            baseActivity.showToast(requestErrBean.getMessage());
            homeViewModel.getErrorLiveData().setValue(null);
        });
        return homeViewModel;
    }
    @Singleton
    @Provides
    ViewModelFactory providesViewModelFactory(Retrofit retrofit,AppDatabase appDatabase){
        return new ViewModelFactory(retrofit,appDatabase);
    }

    @Singleton
    @Provides
    public  Retrofit newRetrofit(){

        return new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(newOkHttpClient())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }



    @Singleton
    @Provides
    public  OkHttpClient newOkHttpClient(){
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                //打印retrofit日志
                Log.i("RetrofitLog","retrofitBack = "+message);
            }
        });

        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addInterceptor(loggingInterceptor);
        builder.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request original=chain.request();
                Request.Builder requestBuilder =original.newBuilder();

                MyApplication myApplication= (MyApplication) mFragmentActivity.getApplication();
                if(myApplication.getToken()!=null){
                    requestBuilder.header("token",myApplication.getToken());
                }
                Request request = requestBuilder.build();
                Response response = chain.proceed(request);
                BufferedSource source = response.body().source();
                source.request(Long.MAX_VALUE); // Buffer the entire body.
                Buffer buffer = source.buffer();
                Charset UTF8 = Charset.forName("UTF-8");
                String string = buffer.clone().readString(UTF8);

                BaseResponse baseResponseBean = new Gson().fromJson(string, BaseResponse.class);
                if (baseResponseBean != null) {
                    if (baseResponseBean.getCode()==10002) {
                        //token过期
                        //根据RefreshToken同步请求，获取最新的Token

                        Intent intent=new Intent(mFragmentActivity, LoginActivity.class);
                         mFragmentActivity.startActivity(intent);
                        //重新请求
                        return response;
                    }
                }

                return response;
            }
        });
        OkHttpClient okHttpClient=  builder.readTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(10, TimeUnit.SECONDS)
                .build();
        return okHttpClient;
    }


}
